# coding:utf-8
from flask import Flask, current_app
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_session import Session
from flask_wtf import CSRFProtect
from config import config_map
import logging
from logging.handlers import RotatingFileHandler, TimedRotatingFileHandler
from datetime import time

import redis

db = SQLAlchemy()
# 数据库迁移工具
migrate = Migrate()

redis_store = None

# # 配置日志信息
# # 创建日志记录器，指明日志保存的路径、每个日志文件的最大大小、保存的日志文件个数上限
# # file_log_handler = RotatingFileHandler("logs/log", maxBytes=1024*1024*100, backupCount=10)

# # 创建日志记录的格式             日志等级    输入日志信息的文件名 行数    日志信息
# formatter = logging.Formatter(
#     '[%(asctime)s] [%(levelname)s] [%(module)s:%(lineno)d] - %(message)s',
#     datefmt='%Y-%m-%d %H:%M:%S'
# )
#
# # 为刚创建的日志记录器设置日志记录格式
# file_log_handler.setFormatter(formatter)
#
# # 为全局的日志工具对象（flask app使用的）添加日记录器
# logging.getLogger().addHandler(file_log_handler)
#
# # 设置日志的记录等级
# logging.basicConfig(level=logging.DEBUG)  # 调试debug级  顺序为  error warn info debug


def create_app(config_name):
    """
    创建工厂模式
    :param config_name: str 配置模式的名字 develop product
    :return:
    """
    app = Flask(__name__)

    # 加载配置
    config_class = config_map.get(config_name)
    app.config.from_object(config_class)

    # 初始化日志系统（优先）
    _configure_logging(app, config_name)

    # 使用app初始化db和数据库迁移工具
    db.init_app(app)
    migrate.init_app(app, db)

    global redis_store
    redis_store = redis.Redis(host=config_class.REDIS_HOST, port=config_class.REDIS_PORT)

    # 使用app初始化session
    Session(app)

    # 使用app初始化csrf防护
    CSRFProtect(app)

    # 延迟导包，避免在导入注册蓝图的时候，里面的视图函数要用到db，而db没有初始化
    from ihome_app import api_1_0
    app.register_blueprint(api_1_0.api, url_prefix="/api/v1.0")
    return app


def _configure_logging(app, config_name):
    """私有方法：配置日志系统"""
    import os
    from datetime import time

    # 确保日志目录存在
    os.makedirs("logs", exist_ok=True)

    # 清空默认处理器
    app.logger.handlers.clear()

    # 根据环境设置日志级别
    log_level = logging.DEBUG if config_name == "develop" else logging.INFO

    # 文件处理器（按天轮转）
    file_handler = TimedRotatingFileHandler(
        "logs/log_back.log",
        when="D",
        interval=1,
        backupCount=30,
        encoding="utf-8",
        utc=False,
        atTime=time(0, 0, 0)
    )
    file_handler.setFormatter(logging.Formatter(
        '[%(asctime)s] [%(levelname)s] [%(module)s:%(lineno)d] - %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S'
    ))

    # 开发环境添加控制台输出
    if config_name == "develop":
        console_handler = logging.StreamHandler()
        console_handler.setFormatter(file_handler.formatter)
        app.logger.addHandler(console_handler)

    app.logger.addHandler(file_handler)
    app.logger.setLevel(log_level)

    # 限制第三方库日志级别
    logging.getLogger("werkzeug").setLevel(logging.WARNING)
    logging.getLogger("sqlalchemy").setLevel(logging.WARNING)